home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 009 / atov_ex.arc / ATOV_EX.C < prev    next >
Encoding:
Text File  |  1986-08-31  |  8.8 KB  |  222 lines

  1. /***************************************************************************/
  2. /*                                                                                                    */
  3. /* atoi_ex, atou_ex, atol_ex, atoul_ex                                                    */
  4. /* Convert a string to an integer extended                                            */
  5. /*                                                                                                    */
  6. /* NAME                                                                                            */
  7. /*     atoi_ex...................Convert a string to an integer                    */
  8. /*     atou_ex...................Convert a string to an unsigined                */
  9. /*     atol_ex...................Convert a string to a long                        */
  10. /*     atoul_ex..................Convert a string to an unsigned long            */
  11. /*                                                                                                 */
  12. /* SYNOPSIS                                                                                        */
  13. /*     result = atoi_ex(p, i);                                                                */
  14. /*     result = atou_ex(p, u);                                                                */
  15. /*     result = atol_ex(p, l);                                                                */
  16. /*     result = atoul_ex(p, ul)                                                            */
  17. /*                                                                                                 */
  18. /*     int result            Result of conversion                                            */
  19. /*                                 0 for end of non-empty input string                    */
  20. /*                                 1 for non-numeric character after non-empty        */
  21. /*                                   input string                                                */
  22. /*                                 2 for empty input string                                */
  23. /*                                 3 for non_numeric character after empty input    */
  24. /*                                   string                                                        */
  25. /*                                 4 for overflow                                                */
  26. /*        char **p                At start, *p points to the string to be converted    */
  27. /*                             At end, *p points to the terminating character.        */
  28. /*                             In the case of overflow, *p points at the             */
  29. /*                             character which caused it.                                    */
  30. /*     int  *i                Pointer to converted integer                                */
  31. /*     unsigned *u            Pointer to converted unsigned                                */
  32. /*     long *l                Pointer to converted long                                    */
  33. /*     unsigned long *ul    Pointer to converted unsigned long                        */
  34. /*                                                                                                 */
  35. /* DESCRIPTION                                                                                    */
  36. /*     The atov_ex functions are extensions of ANSI functions atov.  They    */
  37. /*     each convert the string *p to the proper form of integer.  They        */
  38. /*     extend the standard ANSI functions in three ways:                            */
  39. /*     1.  They skip leading white space.                                                */
  40. /*     2.  They return a pointer to the character of the string after the    */
  41. /*          integer.                                                                            */
  42. /*     3.  They return a result code for the terminating condition.  In        */
  43. /*          particular, they all check for overflow.                                    */
  44. /*     If the input string is empty or has no digits, they all leave the        */
  45. /*        value of their integer unchanged.  This feature allows for default    */
  46. /*     values.                                                                                    */
  47. /*                                                                                                 */
  48. /* CAUTIONS                                                                                        */
  49. /*     Since the ANSI functions return the calculated integer, these            */
  50. /*     functions have a fundamentally different syntax.  They all require    */
  51. /*     an integer value to store this result in.                                        */
  52. /*     These functions are specific to the 8088 and its family.  In             */
  53. /*     addition, _natoil.asm, which actually does most of the work for         */
  54. /*     them, uses Lattice C, Version 3.10 conventions and DOS.MAC, the        */
  55. /*     Lattice INCLUDE file which implements them.  They should be                */
  56. /*     compatible with Version 3.00 as well.  I am not sure about                */
  57. /*     Version 2 or other brands of C                                                    */
  58. /*                                                                                                    */
  59. /* RETURNS                                                                                        */
  60. /*     All functions return an integer result code.                                    */
  61. /*                                                                                                 */
  62. /*  EXAMPLES                                                                                    */
  63. /*                                                                                                    */
  64. /*         Assume that s contains "   -1000000, 50000".                                */
  65. /*                                                                                                 */
  66. /*         char **p;                                                                            */
  67. /*            long l1, l2;                                                                        */
  68. /*                                                                                                 */
  69. /*         p = &s;                                                                                */
  70. /*         if (atol_ex(p, &l1) == 4)                                                        */
  71. /*             {                                                                                    */
  72. /*                    fputs("Overflow", stderr);                                                */
  73. /*                    break;                                                                        */
  74. /*                }                                                                                    */
  75. /*                                                                                                 */
  76. /*         *p points to the comma, and *l2 contains -1000000.  The function    */
  77. /*         actually returned 1.                                                                */
  78. /*                                                                                                 */
  79. /*         if (atol_ex(p, &l2) == 4)                                                        */
  80. /*             {                                                                                    */
  81. /*                    fputs("Overflow", stderr);                                                */
  82. /*                    break;                                                                        */
  83. /*                }                                                                                    */
  84. /*                                                                                                 */
  85. /*         *p points to the NULL at the end of s, and *l2 contains 50000.        */
  86. /*         The function actually returned 0.                                            */
  87. /*                                                                                                 */
  88. /***************************************************************************/
  89. /*                                                                                                 */
  90. /* COMPILATION                                                                                    */
  91. /*        Compile the four functions for the small model with Lattice C as:        */
  92. /*            "lcs -oatoi_ex atov_ex" for atoi_ex.obj                                    */
  93. /*            "lcs -oatol_ex -dL_EX atov_ex" for atol_ex.obj                            */
  94. /*            "lcs -oatou_ex -dU_EX atov_ex" for atou_ex.obj                            */
  95. /*            "lcs -oatoul_ex -dL_EX -dU_EX atov_ex" for atoul.obj                    */
  96. /*        For other memory models, change "lcs" to the proper compiler call        */
  97. /*                                                                                                    */
  98. /* Written by:        Lew Paper                                                                */
  99. /* Date written:    8/28/86                                                                    */
  100. /*                                                                                                 */
  101. /***************************************************************************
  102. */
  103.  
  104. #include <limits.h>
  105.  
  106. #ifdef L_EX                                                    /* Long */
  107. #define _NATOV _natol                                    /* Inner conversion function */
  108. #define NINT_TYPE unsigned long                        /* Type of value from _NATOV */
  109. #ifdef U_EX                                                    /* Unsigned long */
  110. #define ATOV_EX atoul_ex                                /* Function name */
  111. #define INTEGER ul                                        /* Converted value */
  112. #define INT_TYPE unsigned long                        /* Type of INTEGER */
  113. #define MAX_VALUE ULONG_MAX                            /* Maximum value for type */
  114. #else                                                            /* Signed long */
  115. #define ATOV_EX atol_ex                                    /* Function name */
  116. #define INTEGER l                                            /* Converted value */
  117. #define INT_TYPE long                                    /* Type of INTEGER */
  118. #define MAX_VALUE LONG_MAX                                /* Maximum value for type */
  119. #define MIN_VALUE LONG_MIN                                /* Minimum value for type */
  120. #endif                                                        /* #ifdef U_EX */
  121. #else                                                            /* Standard length */
  122. #define _NATOV _natoi                                    /* Inner conversion function */
  123. #define NINT_TYPE unsigned                                /* Type of value from _NATOV */
  124. #ifdef U_EX                                                    /* Unsigned int */
  125. #define ATOV_EX atou_ex                                    /* Function name */
  126. #define INTEGER u                                            /* Converted value */
  127. #define INT_TYPE unsigned                                /* Type of converted value */
  128. #define MAX_VALUE UINT_MAX                                /* Maximum value for type */
  129. #else                                                            /* Signed int */
  130. #define ATOV_EX atoi_ex                                    /* Function name */
  131. #define INTEGER i                                            /* Converted value */
  132. #define INT_TYPE int                                        /* Type of converted value */
  133. #define MAX_VALUE INT_MAX                                /* Maximum value for type */
  134. #define MIN_VALUE INT_MIN                                /* Minimum value for type */
  135. #endif                                                        /* #ifdef U_EX */
  136. #endif                                                        /* #ifdef L_EX     */
  137.  
  138. int ATOV_EX(p, INTEGER)
  139. char **p;
  140. INT_TYPE *INTEGER;
  141.  
  142. {
  143. #ifndef U_EX                                                /* Unsigned */
  144.     int sign;                                                /* -1 if negative */
  145. #endif                                                        /* #ifndef U_EX */
  146.     int result;
  147.     union
  148.     {
  149.         NINT_TYPE ninteger;                                /* Value from _NATOV - the */
  150.                                                                 /* inner conversion */
  151.         INT_TYPE cinteger;                                /* Value for outer */
  152.                                                                 /* conversion */
  153.     } number;
  154.  
  155.     while (isspace(**p))                                    /* Skip white space */
  156.         (*p)++;
  157.  
  158. #ifndef U_EX                                                /* Check for sign */
  159.     sign = 1;                                                /* Assume positive */
  160.     switch (**p)
  161.     {
  162.         case '-':
  163.             sign = -1;                                        /* Negative */
  164.             (*p)++;                                            /* Next character */
  165.             break;
  166.         case '+':
  167.             (*p)++;                                            /* Next character */
  168.             break;
  169.     }
  170. #endif                                                        /* #ifndef U_EX */
  171.  
  172.     result = _NATOV(p, &number.ninteger);
  173.     switch (result)
  174.     {
  175. #ifdef U_EX                                                    /* Unsigned */
  176.         case 0:                                                /* Number at end of string */
  177.         case 1:                                                /* Number inside string */
  178.             *INTEGER = number.cinteger;
  179.             break;
  180.  
  181.         case 4:                                                /* Overflow */
  182.             *INTEGER = MAX_VALUE;                        /* Maximum possible value */
  183.             break;
  184. #else                                                            /* Signed */
  185.         case 0:                                                /* Number at end of string */
  186.         case 1:                                                /* Number inside string */
  187.             if (number.cinteger >= 0)                    /* No overflow? */
  188.             {                                                    /* Yes */
  189.                 if (sign < 0)
  190.                     *INTEGER = -number.cinteger;
  191.                 else
  192.                     *INTEGER = number.cinteger;
  193.             }
  194.             else
  195.             {
  196.                 if (sign < 0)
  197.                 {
  198.                     if (number.cinteger > MIN_VALUE)    /* Is it overflow? */
  199.                         result = 4;                            /* Yes */
  200.                     *INTEGER = MIN_VALUE;                /* Minium possible value */
  201.                 }
  202.                 else                                            /* Positive value must be */
  203.                                                                 /* overflow */
  204.                 {
  205.                     *INTEGER = MAX_VALUE;                /* Maximum possible value */
  206.                     result = 4;
  207.                 }
  208.             }
  209.         break;
  210.  
  211.         case 4:                                                /* Overflow */
  212.             if (sign < 0)
  213.                 *INTEGER = MIN_VALUE;                    /* Minimum possible value */
  214.             else
  215.                 *INTEGER = MAX_VALUE;                    /* Maximum possible value */
  216.             break;
  217. #endif                                                        /* #ifdef U_EX */
  218.     }
  219.     
  220.     return(result);
  221. }
  222.